package zouran.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.model.ObjectMetadata;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import zouran.entity.FileOperation;
import zouran.exception.MyRunTimeException;
import zouran.mapper.FileOperationMapper;
import zouran.result.ErrorMessage;
import zouran.service.EarthquakeInfoService;
import zouran.service.FileOperationService;
import zouran.util.COSFileUtil;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


/**
 * @author zouran
 * createDate：2024/8/6  5:42
 */
@Service
public class FileOperationServiceImpl extends ServiceImpl<FileOperationMapper, FileOperation> implements FileOperationService {
    private final FileOperationMapper fileOperationMapper;
    private final EarthquakeInfoService earthquakeInfoService;
    @Value("${tencent-cos.secret-id}")
    private String secretId;
    @Value("${tencent-cos.secret-key}")
    private String secretKey;
    @Value("${tencent-cos.region-name}")
    private String regionName;
    @Value("${tencent-cos.bucket-name}")
    private String bucketName;
    @Value("${tencent-cos.exist-time}")
    private Integer existTime;

    public FileOperationServiceImpl(FileOperationMapper fileOperationMapper, EarthquakeInfoService earthquakeInfoService) {
        this.fileOperationMapper = fileOperationMapper;
        this.earthquakeInfoService = earthquakeInfoService;
    }

    /**
     * @param fileName 文件名
     * @return 文件后缀，不存在则返回''
     */
    private String getFileExtension(String fileName) {
        int dotIndex = fileName.lastIndexOf('.');
        return (dotIndex > 0 && dotIndex < fileName.length() - 1) ? (fileName.substring(dotIndex + 1)).toLowerCase() : "";
    }

    public boolean checkFileExist(String filePath) {
        return COSFileUtil.check(filePath, secretId, secretKey, regionName, bucketName);
    }

    @Override
    public boolean updateFileStatus(Long id) {
        FileOperation fileOperation = fileOperationMapper.selectById(id);
        if (fileOperation == null)
            throw new MyRunTimeException(ErrorMessage.FILE_ID_ERROR.getMessage());
        if (checkFileExist(fileOperation.getUrl())) {
            ObjectMetadata objectMetadata = COSFileUtil.getObjectMetadata(fileOperation.getUrl(), secretId, secretKey, regionName, bucketName);
            fileOperation.setIsExist(1);
            fileOperation.setTime(LocalDateTime.now());
            fileOperation.setSize(objectMetadata.getContentLength());
            return fileOperationMapper.updateById(fileOperation) == 1;
        } else return false;
    }

    @Override
    public String getFileCosUrl(String fileName) {
//        资源不存在时也会返回一个链接
        return COSFileUtil.generatePresignedUrl(fileName, 30, HttpMethodName.GET, secretId, secretKey, regionName, bucketName);
    }

    @Override
    public Map<String, Object> insertFileInfo(Long earthquakeId, String fileName, String description) {
//        判断地震编号是否有误
        if (!earthquakeInfoService.judgeEarthquakeInfoExistById(earthquakeId))
            throw new MyRunTimeException(ErrorMessage.EARTHQUAKE_ID_ERROR.getMessage());
        //生成文件名
        String suffix = getFileExtension(fileName);
        String saveUrl = String.valueOf(UUID.randomUUID());
        if (!suffix.isEmpty()) {
            saveUrl = saveUrl + "." + suffix;
        }
        FileOperation fileOperation = new FileOperation(null, earthquakeId, fileName, saveUrl, null, suffix, null, 0, description, null);
        Map<String, Object> map = new HashMap<>();
        if (fileOperationMapper.insert(fileOperation) == 1) {
            map.put("url", COSFileUtil.generatePresignedUrl(saveUrl, existTime, HttpMethodName.PUT, secretId, secretKey, regionName, bucketName));
            map.put("fileId", fileOperation.getId());
        }
        return map;
    }

    @Override
    public IPage<FileOperation> queryFileListById(Map<String, Object> params) {
        Long earthquakeId = ((Integer) params.get("earthquakeId")).longValue();
        long page = 0, size = 5;
        if (params.containsKey("page")) {
            page = ((Integer) params.get("page")).longValue();
        }
        if (params.containsKey("size")) {
            size = ((Integer) params.get("size")).longValue();
        }
        Page<FileOperation> fileOperationPage = new Page<>(page, size);
        return fileOperationMapper.getFileInfoList(earthquakeId, fileOperationPage, params);
    }
}
